// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Text.Json.Serialization;
using Docfx.Common;
using Docfx.Plugins;

using Newtonsoft.Json;

namespace Docfx;

/// <summary>
/// BuildJsonConfig.
/// </summary>
/// <see href="https://dotnet.github.io/docfx/reference/docfx-json-reference.html#12-properties-for-build"/>
internal class BuildJsonConfig
{
    /// <summary>
    /// Contains all the files to generate documentation, including metadata yml files and conceptual md files.
    /// </summary>
    [JsonProperty("content")]
    [JsonPropertyName("content")]
    public FileMapping Content { get; set; }

    /// <summary>
    /// Contains all the resource files that conceptual and metadata files dependent on, e.g. image files.
    /// </summary>
    [JsonProperty("resource")]
    [JsonPropertyName("resource")]
    public FileMapping Resource { get; set; }

    /// <summary>
    /// Contains all the conceptual files which contains yaml header with uid and is intended to override the existing metadata yml files.
    /// </summary>
    [JsonProperty("overwrite")]
    [JsonPropertyName("overwrite")]
    public FileMapping Overwrite { get; set; }

    /// <summary>
    /// Specifies the urls of xrefmap used by content files. Supports local file path and HTTP/HTTPS urls.
    /// </summary>
    [JsonProperty("xref")]
    [JsonPropertyName("xref")]
    public ListWithStringFallback Xref { get; set; }

    /// <summary>
    /// Defines the output folder of the generated build files.
    /// Command line --output argument prepends this value.
    /// </summary>
    [JsonProperty("dest")]
    [JsonPropertyName("dest")]
    public string Dest { get; set; }

    /// <summary>
    /// Defines the output folder of the generated build files.
    /// Command line --output argument override this value.
    /// </summary>
    [JsonProperty("output")]
    [JsonPropertyName("output")]
    public string Output { get; set; }

    /// <summary>
    /// Contains metadata that will be applied to every file, in key-value pair format.
    /// </summary>
    [JsonProperty("globalMetadata")]
    [JsonPropertyName("globalMetadata")]
    [Newtonsoft.Json.JsonConverter(typeof(JObjectDictionaryToObjectDictionaryConverter))]
    public Dictionary<string, object> GlobalMetadata { get; set; }

    /// <summary>
    /// Specify a list of JSON file path containing globalMetadata settings.
    /// </summary>
    [JsonProperty("globalMetadataFiles")]
    [JsonPropertyName("globalMetadataFiles")]
    public ListWithStringFallback GlobalMetadataFiles { get; set; } = [];

    /// <summary>
    /// Metadata that applies to some specific files.
    /// The key is the metadata name.
    /// For each item of the value:
    ///     The key is the glob pattern to match the files.
    ///     The value is the value of the metadata.
    /// </summary>
    [JsonProperty("fileMetadata")]
    [JsonPropertyName("fileMetadata")]
    public Dictionary<string, FileMetadataPairs> FileMetadata { get; set; }

    /// <summary>
    /// Specify a list of JSON file path containing fileMetadata settings.
    /// </summary>
    [JsonProperty("fileMetadataFiles")]
    [JsonPropertyName("fileMetadataFiles")]
    public ListWithStringFallback FileMetadataFiles { get; set; } = [];

    /// <summary>
    /// The templates applied to each file in the documentation. It can be a string or an array.
    /// The latter ones will override the former ones if the name of the file inside the template collides.
    /// If omitted, embedded default template will be used.
    /// </summary>
    [JsonProperty("template")]
    [JsonPropertyName("template")]
    public ListWithStringFallback Template { get; set; } = [];

    /// <summary>
    /// The themes applied to the documentation.
    /// Theme is used to customize the styles generated by template.
    /// It can be a string or an array.
    /// The latter ones will override the former ones if the name of the file inside the template collides.
    /// If omitted, no theme will be applied, the default theme inside the template will be used.
    /// </summary>
    [JsonProperty("theme")]
    [JsonPropertyName("theme")]
    public ListWithStringFallback Theme { get; set; }

    /// <summary>
    /// Specify PostProcessor array.
    /// Build-in HtmlProcessor is automatically added by default.
    /// </summary>
    ///  <example>
    ///  <code>
    ///  "postProcessors": ["ExtractSearchIndex"]
    ///  </code>
    ///  </example>
    [JsonProperty("postProcessors")]
    [JsonPropertyName("postProcessors")]
    public ListWithStringFallback PostProcessors { get; set; } = [];

    /// <summary>
    /// Run in debug mode. With debug mode, raw model and view model will be exported
    /// automatically when it encounters error when applying templates.
    /// If not specified, it is false
    /// </summary>
    [JsonProperty("debug")]
    [JsonPropertyName("debug")]
    public bool? Debug { get; set; }

    /// <summary>
    /// The output folder for files generated for debugging purpose when in debug mode.
    /// If not specified, it is ${TempPath}/docfx
    /// </summary>
    [JsonProperty("debugOutput")]
    [JsonPropertyName("debugOutput")]
    public string DebugOutput { get; set; }

    /// <summary>
    /// If set to true, data model to run template script will be extracted in .raw.model.json extension.
    /// </summary>
    [JsonProperty("exportRawModel")]
    [JsonPropertyName("exportRawModel")]
    public bool? ExportRawModel { get; set; }

    /// <summary>
    /// Specify the output folder for the raw model.
    /// If not set, the raw model will be generated to the same folder as the output documentation.
    /// </summary>
    [JsonProperty("rawModelOutputFolder")]
    [JsonPropertyName("rawModelOutputFolder")]
    public string RawModelOutputFolder { get; set; }

    /// <summary>
    /// If set to true, data model to apply template will be extracted in .view.model.json extension.
    /// </summary>
    [JsonProperty("exportViewModel")]
    [JsonPropertyName("exportViewModel")]
    public bool? ExportViewModel { get; set; }

    /// <summary>
    /// Specify the output folder for the view model.
    /// If not set, the view model will be generated to the same folder as the output documentation.
    /// </summary>
    [JsonProperty("viewModelOutputFolder")]
    [JsonPropertyName("viewModelOutputFolder")]
    public string ViewModelOutputFolder { get; set; }

    /// <summary>
    /// If set to true, template will not be actually applied to the documents.
    /// This option is always used with --exportRawModel or --exportViewModel is set so that only raw model files or view model files are generated.
    /// </summary>
    [JsonProperty("dryRun")]
    [JsonPropertyName("dryRun")]
    public bool? DryRun { get; set; }

    /// <summary>
    /// Set the max parallelism, 0 is auto.
    /// </summary>
    [JsonProperty("maxParallelism")]
    [JsonPropertyName("maxParallelism")]
    public int? MaxParallelism { get; set; }

    /// <summary>
    /// Set the parameters for markdown engine, value should be a JSON string.
    /// </summary>
    [JsonProperty("markdownEngineProperties")]
    [JsonPropertyName("markdownEngineProperties")]
    public MarkdownServiceProperties MarkdownEngineProperties { get; set; }

    /// <summary>
    /// Set the name of ICustomHrefGenerator derived class.
    /// </summary>
    [JsonProperty("customLinkResolver")]
    [JsonPropertyName("customLinkResolver")]
    public string CustomLinkResolver { get; set; }

    /// <summary>
    /// Specifies the output folder of specified group name.
    /// </summary>
    /// <example>
    /// <code>
    /// groups:{
    ///   "v1": {
    ///     "dest": "output_dir_v1"
    ///   }
    /// }
    /// </code>
    /// </example>
    [JsonProperty("groups")]
    [JsonPropertyName("groups")]
    public Dictionary<string, GroupConfig> Groups { get; set; }

    /// <summary>
    /// Specifies the options for the sitemap.xml file.
    /// </summary>
    [JsonProperty("sitemap")]
    [JsonPropertyName("sitemap")]
    public SitemapOptions Sitemap { get; set; }

    /// <summary>
    /// Disable fetching Git related information for articles.
    /// By default it is enabled and may have side effect on performance when the repo is large.
    /// </summary>
    [JsonProperty("disableGitFeatures")]
    [JsonPropertyName("disableGitFeatures")]
    public bool DisableGitFeatures { get; set; }
}
